package com.remark.service.impl;


import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.remark.dto.Result;
import com.remark.entity.ShopType;
import com.remark.mapper.ShopTypeMapper;
import com.remark.service.IShopTypeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;


import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import static com.remark.utils.RedisConstants.CACHE_SHOP_TYPE_KEY;


/**
 * <p>
 *  服务实现类
 * </p>
 */
@Service
public class ShopTypeServiceImpl extends ServiceImpl<ShopTypeMapper, ShopType> implements IShopTypeService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    //基于String实现店铺类型查询业务缓存
    @Override
    public Result queryShopTypeString() {

        //1.从redis中查询缓存
        String key=CACHE_SHOP_TYPE_KEY;
        String shopTypeJson=stringRedisTemplate.opsForValue().get(key);

        List<ShopType> typeList=null;
        //2.判断缓存是否存在
        if(StrUtil.isNotBlank(shopTypeJson)){
            //3.存在，直接返回(将json转为对象,即反序列化)
            //JSONUtil工具类中的toList方法，将名为shopTypeJson的JSON字符串转换为一个ShopType类的对象列表。
            typeList= JSONUtil.toList(shopTypeJson,ShopType.class);//反序列化
            return Result.ok(typeList);
        }
        //4.不存在，查询数据库
        typeList= query().orderByAsc("sort").list();
        //查询数据库中是否存在
        if(typeList==null)
        {
            //不存在，返回错误信息
            return Result.fail("店铺类型不存在");
        }
        //存在，将数据存入redis然后返回
        stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(typeList));//将对象转为json字符串，即序列化
        return Result.ok(typeList);
    }

    //基于List实现店铺类型查询业务缓存
    @Override
    public Result queryShopTypeList() {
        //1.从redis中查询缓存
        String key=CACHE_SHOP_TYPE_KEY;
        /*range(key, 0, -1)：这是opsForList接口的一个方法，用于获取列表中的元素。key是列表的键名，
        0表示从列表的第一个元素开始，-1表示获取到列表的最后一个元素。因此，range(key, 0, -1)表示获取整个列表。*/
        List<String> shopTypeList=stringRedisTemplate.opsForList().range(key,0,-1);
        //2.判断缓存是否存在
        if(shopTypeList!=null && !shopTypeList.isEmpty()){
            //3.存在，直接返回(将json转为对象,即反序列化,然后再一一添加到typeList中,最后返回)
            ArrayList<ShopType> typeList=new ArrayList<>();
            for(String str:shopTypeList){
                typeList.add(JSONUtil.toBean(str,ShopType.class));
            }
            return Result.ok(typeList);
        }
        //4.redis中不存在，查询数据库
        List<ShopType> typeList= query().orderByAsc("sort").list();
        //判断数据库中是否存在
        if(typeList==null||typeList.isEmpty()){
            //不存在，返回错误信息
            return Result.fail("店铺类型不存在");
        }
        //存在，将数据存入redis然后返回
        for(ShopType shopType:typeList){
            stringRedisTemplate.opsForList().rightPushAll(key,JSONUtil.toJsonStr(shopType));
        }
        return Result.ok(typeList);
    }

    //基于Zset实现店铺类型查询业务缓存
    @Override
    public Result queryShopTypeZset() {
        //1.从redis中查询缓存
        String key=CACHE_SHOP_TYPE_KEY;
        Set<String> shopTypeSet=stringRedisTemplate.opsForZSet().range(key,0,-1);
        //2.判断redis中是否有该缓存
        if(shopTypeSet.size()!=0){
            //存在，直接返回(将json转为对象,即反序列化,然后再一一添加到typeList中,最后返回)
            List<ShopType> typeList=new ArrayList<>();
            for(String str:shopTypeSet){
                typeList.add(JSONUtil.toBean(str,ShopType.class));
            }
            return Result.ok(typeList);
        }
        //3.redis中不存在，查询数据库
        List<ShopType> typeList=query().orderByAsc("sort").list();
        //判断数据库中是否存在
        if(typeList==null||typeList.isEmpty()){
            //数据库中也不存在，返回错误信息
            return Result.fail("店铺类型不存在");
        }
        //数据库中存在，将数据存入redis然后返回
        for(ShopType shopType:typeList){
            stringRedisTemplate.opsForZSet().add(key,JSONUtil.toJsonStr(shopType),shopType.getSort());

        }
        return Result.ok(typeList);
    }
}
